package com.oneinlet.client

import com.oneinlet.*
import com.oneinlet.client.handler.ClientProxyHandler
import com.oneinlet.client.handler.YClientHandler
import io.netty.bootstrap.Bootstrap
import io.netty.channel.ChannelInitializer
import io.netty.channel.nio.NioEventLoopGroup
import io.netty.channel.socket.SocketChannel
import io.netty.channel.socket.nio.NioSocketChannel
import io.netty.handler.timeout.IdleStateHandler
import org.slf4j.LoggerFactory

/**
 * Created by WangZiHe on 2017/10/6
 * QQ/WeChat:648830605
 * QQ-Group:368512253
 * Blog:www.520code.net
 * Github:https://github.com/yancheng199287
 */

class YClient(private val serverHost: String, private val serverPort: Int) {

    private val logger = LoggerFactory.getLogger("YClient")

    private lateinit var b: Bootstrap
    private val maxConnectCount = 5000
    private var reConnectCount = maxConnectCount

    fun startYClient() {
        val group = NioEventLoopGroup()
        val bootstrap = Bootstrap()
        bootstrap.group(group)
                .channel(NioSocketChannel::class.java)
                .handler(object : ChannelInitializer<SocketChannel>() {
                    override fun initChannel(ch: SocketChannel?) {
                        ch!!.pipeline()
                                .addLast(ClientProxyHandler())
                    }
                })
        b = Bootstrap()
        try {
            b.group(group)
                    .channel(NioSocketChannel::class.java)
                    .remoteAddress(serverHost, serverPort)
                    .handler(object : ChannelInitializer<SocketChannel>() {
                        override fun initChannel(ch: SocketChannel?) {
                            ch!!.pipeline()
                                    //我读他写， 我写他读，   读的要比的时间大点  就ok
                                    .addLast(IdleStateHandler(25, 20, 0))
                                    .addLast(YCMessageDecoder())
                                    .addLast(YCMessageEncoder())
                                    .addLast(YClientHandler(bootstrap))
                        }
                    })

            val future = b.connect().sync()
            future.channel().closeFuture().sync()
        } finally {
            group.shutdownGracefully()
            Thread.sleep(5000)
            if (reConnectCount > 0) {
                reConnectCount--
                logger.info("正在尝试重新连接服务器,已经尝试次数：${maxConnectCount - reConnectCount}, 还剩下 $reConnectCount 次")
                startYClient()
                reConnectCount = maxConnectCount
            } else {
                logger.info("尝试重连次用完，连接断开，请检查本服务端和本地的转发服务是否开启")
            }
        }

    }


}